# -*- coding: utf-8 -*-
import logging

from future.utils import raise_with_traceback

from common import orm
from common.account.db.account import add_campaign_award_in_transaction
from common.notification.handler import notify_recharge_success
from common.treasure.model import Treasure, TREASURE_CONF, TREASURE_STATUS
from common.utils.decorator import sql_wrapper
from common.utils.exceptions import (ResourceNotFound)
from common.utils.tz import today_str

_LOGGER = logging.getLogger(__name__)


@sql_wrapper
def create_treasure(user_id, treasure_type):
    treasure = Treasure()
    treasure.user_id = user_id
    treasure.amount = 0
    # treasure.treasure_type = TREASURE_TYPE.get_value(treasure_type) # 宝箱类型
    treasure.treasure_type = treasure_type  # 宝箱类型
    treasure.status = TREASURE_STATUS.UNOPEN
    treasure.date = today_str()
    treasure.save()


@sql_wrapper
def get_treasures(user_id):
    query = Treasure.query.filter(Treasure.user_id == user_id).filter(Treasure.date == today_str()).all()
    return query


@sql_wrapper
def get_user_treasure(user_id, limit=0, offset=0):
    query = Treasure.query.filter(Treasure.user_id == user_id)
    query = query.order_by(Treasure.id.desc()).order_by(
        Treasure.created_at.desc())
    if limit > 0:
        query = query.limit(limit)
    if offset > 0:
        query = query.offset(offset)
    return query.all()


@sql_wrapper
def get_treasure_by_type(user_id, treasure_type):
    treasure = Treasure.query.filter(
        Treasure.user_id == user_id).filter(
        Treasure.date == today_str()).filter(
        Treasure.treasure_type == treasure_type).first()
    return treasure


@sql_wrapper
def get_treasure_type_for_id(user_id, treasure_id):
    treasure = Treasure.query.filter(Treasure.id == treasure_id).filter(Treasure.user_id == user_id).first()
    if not treasure:
        raise ResourceNotFound('treasure id invalid')
    return treasure.treasure_type


@sql_wrapper
def open_treasure(id, amount):
    Treasure.query.filter(Treasure.id.in_(id)).update({
        'status': TREASURE_STATUS.OPENED,
        'amount': amount,
    })
    orm.session.commit()


def get_qualified_treasures(amount):
    result = []
    for k in TREASURE_CONF:
        if float(amount) >= k:
            result.append(TREASURE_CONF[k])
    return result


def create_treasure_for_user(user_id, amount):
    for treasure_type in get_qualified_treasures(amount):
        treasure = get_treasure_by_type(user_id, treasure_type)
        if not treasure:
            create_treasure(user_id, treasure_type)


def award_daily_treasure(user_id, treasure_id, amount, date_str):
    try:
        extend = {
            'title': u'抽宝箱',
            'award_amount': amount
        }
        daily_treasure = Treasure.query.with_for_update(). \
            filter(Treasure.id == treasure_id). \
            filter(Treasure.user_id == user_id). \
            filter(Treasure.date == date_str). \
            filter(Treasure.transaction_id.is_(None)). \
            filter(Treasure.status == TREASURE_STATUS.UNOPEN).first()

        if daily_treasure:
            transaction_id = add_campaign_award_in_transaction(user_id, amount, extend)
            daily_treasure.status = TREASURE_STATUS.OPENED
            daily_treasure.amount = amount
            daily_treasure.transaction_id = transaction_id
            daily_treasure.save(auto_commit=False)
            orm.session.commit()
            notify_recharge_success(user_id, u'抽宝箱', amount)
        else:
            orm.session.commit()
    except Exception as e:
        orm.session.rollback()
        orm.session.close()
        raise_with_traceback(e)
